
import WujieVue from 'wujie-vue2'
import { router } from './router'
import { store } from './store'
import CommonUtil from '@zh/common-utils/utils/common'
import storage from '@zh/common-utils/utils/storage'

import { isValidToken } from './api/auth'

const { setupApp, preloadApp, bus } = WujieVue

const apps = []

function fetch (url, options) {
  return window.fetch(url, { ...options, credentials: 'omit' })
}

const MicroApp = (Vue) => {
  Vue.use(WujieVue)

  MicroApp.lifeCycles.loadError = (url, e) => {
    store.hideLoading()
    Vue.prototype.$notify?.error('加载微应用失败')
    process.env.NODE_ENV == 'development' && console.info(`${url} 加载失败`, e)
  }

  bus.$on('route-change', (name, path) => {
    !path.startsWith('/') && (path = `/${path}`)
    path = `/${name}${path}`
    if (router.currentRoute.path != path) {
      router.push(path)
    }
  })
}

/**
 * 微应用生命周期钩子
 */
MicroApp.lifeCycles = {
  beforeLoad: (appWindow) => {
    store.showLoading()
    process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} beforeLoad`)
  },
  beforeMount: (appWindow) => process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} beforeMount`),
  /**
   * 非保活子应用 mount 之后调用
   * @param {*} appWindow
   */
  afterMount: (appWindow) => {
    store.hideLoading()
    process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} afterMount`)
  },
  /**
   * 子应用 unmount 之前调用
   * @param {*} appWindow
   * @returns
   */
  beforeUnmount: (appWindow) => process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} beforeUnmount`),
  /**
   * 子应用 unmount 之后调用
   * @param {*} appWindow
   * @returns
   */
  afterUnmount: (appWindow) => process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} afterUnmount`),
  /**
   * 保活子应用进入时触发
   * @param {*} appWindow
   */
  activated: (appWindow) => {
    store.hideLoading()
    process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} activated`)
  },
  /**
   * 保活子应用离开时触发
   * @param {*} appWindow
   * @returns
   */
  deactivated: (appWindow) => process.env.NODE_ENV == 'development' && console.info(`${appWindow.__WUJIE.id} deactivated`),
  /**
   * 子应用加载失败时触发
   * @param {*} url
   * @param {*} e
   */
  loadError: (url, e) => process.env.NODE_ENV == 'development' && console.info(`${url} 加载失败`, e)
}
MicroApp.props = {
  /**
   * 验证 Token 是否有效
   */
  isValidToken: isValidToken,
  /**
   * 获取 Token 包括有效时间
   * @returns
   */
  getToken: () => storage.getToken(),
  /**
   * 获取登录用户信息
   * @returns
   */
  getLoginUser: () => store.getLoginUser(),
  /**
   * 重定向登录
   */
  redirectLogin () {
    router.redirectLogin()
  },
  /**
   * 显示遮罩
   */
  showLoading: () => store.showLoading(),
  /**
   * 隐藏遮罩
   */
  hideLoading: () => store.hideLoading(),
  /**
   * 后退
   * @returns
   */
  back () {
    router.back()
  },
  go (n) {
    router.go(n)
  },
  push (route) {
    if (typeof (route) === 'string') {
      route = { path: route }
    }
    if (router.currentRoute.path != route.path) {
      router.push(route)
    }
  }
}

MicroApp.setupApp = (name, url, options) => {
  if (apps.includes(name)) {
    return
  }
  if (!name || !url) {
    return
  }
  options = CommonUtil.merge({
    exec: true,
    degrade: false,
    // 保活
    alive: true,
    props: { ...MicroApp.props, name, url },
    fetch,
    ...MicroApp.lifeCycles
  }, options || {})
  options = { ...options, name, url }
  setupApp(options)
  apps.push(name)
  return options
}

MicroApp.preloadApp = (microapp, rootpath) => {
  return new Promise((resolve, reject) => {
    const preloadApps = store.getAppConfig('preloadApps')
    if (microapp && preloadApps.includes(microapp)) {
      preloadApp({
        name: rootpath && rootpath != '/' ? `${rootpath}-${microapp}` : microapp,
        // 加载表单三方业务组件
        props: {
          ...MicroApp.props,
          preload: true
        },
        ...MicroApp.lifeCycles,
        loadError () {
          store.hideLoading()
          reject(new Error('预加载微应用失败'))
        },
        afterMount () {
          store.hideLoading()
          resolve()
        }
      })
    } else {
      resolve()
    }
  })
}

export default MicroApp